﻿using System;
using System.Runtime.CompilerServices;
using UnityEngine.ResourceManagement.AsyncOperations;

namespace Function.SAsset
{
    public static class IAsyncOperationExtensions
    {
        public static AsyncOperationAwaiter GetAwaiter(this AsyncOperationHandle operation)
        {
            return new AsyncOperationAwaiter(operation);
        }

        public static AsyncOperationAwaiter<T> GetAwaiter<T>(this AsyncOperationHandle<T> operation) where T : class
        {
            return new AsyncOperationAwaiter<T>(operation);
        }

        public readonly struct AsyncOperationAwaiter : INotifyCompletion
        {
            private readonly AsyncOperationHandle KOperation;

            public AsyncOperationAwaiter(AsyncOperationHandle operation)
            {
                KOperation = operation;
            }

            public bool IsCompleted => KOperation.Status != AsyncOperationStatus.None;

            public void OnCompleted(Action continuation)
            {
                KOperation.Completed += (op) => continuation?.Invoke();
            }

            public object GetResult()
            {
                return KOperation.Result;
            }
        }

        public readonly struct AsyncOperationAwaiter<T> : INotifyCompletion where T : class
        {
            private readonly AsyncOperationHandle<T> KOperation;

            public AsyncOperationAwaiter(AsyncOperationHandle<T> operation)
            {
                KOperation = operation;
            }

            public bool IsCompleted => KOperation.Status != AsyncOperationStatus.None;

            public void OnCompleted(Action continuation)
            {
                KOperation.Completed += (op) => continuation?.Invoke();
            }

            public T GetResult()
            {
                return KOperation.Result;
            }
        }
    }
}